package com.bwie.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.mapper.TbGiftRecordMapper;
import com.bwie.mapper.TbGiftStrategyMapper;
import com.bwie.pojo.*;
import com.bwie.service.TbGiftService;
import com.bwie.mapper.TbGiftMapper;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import com.bwie.vo.PageInfoVo;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.micrometer.core.instrument.binder.BaseUnits;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.security.Key;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author 31803
 * @description 针对表【tb_gift】的数据库操作Service实现
 * @createDate 2025-07-15 11:47:16
 */
@Service
public class TbGiftServiceImpl extends ServiceImpl<TbGiftMapper, TbGift>
        implements TbGiftService {

    @Autowired
    TbGiftMapper tbGiftMapper;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    FastFileStorageClient fileStorageClient;

    @Autowired
    HttpServletRequest request;

    @Autowired
    TbGiftRecordMapper tbGiftRecordMapper;

    @Autowired
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Autowired
    KafkaTemplate kafkaTemplate;

    @Autowired
    TbGiftStrategyMapper tbGiftStrategyMapper;



    @Override
    public R getGiftPage(PageInfoVo pageInfoVo) {
        //构造分页参数
        Page<TbGift> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());

        //查询
        Page<TbGift> tbGiftPage = tbGiftMapper.selectGiftPage(page, pageInfoVo);
        return R.ok().setData(tbGiftPage);
    }

    @Override
    public R getDictListById(Integer typeId) {
        String key = "dict-" + typeId;
        HashOperations<String, Object, Object> forHash = redisTemplate.opsForHash();
        ArrayList<TbDict> tbDicts = new ArrayList<>();
        List<Object> values = forHash.values(key);
        for (Object value : values) {
            TbDict tbDict = JSON.parseObject(value.toString(), TbDict.class);
            tbDicts.add(tbDict);
        }

        return R.ok().setData(tbDicts);
    }

    @Override
    public R uploadImage(MultipartFile file) {
        try {
            String extName = FileNameUtil.extName(file.getOriginalFilename());
            StorePath storePath = fileStorageClient.uploadFile(file.getInputStream(), file.getSize(), extName, null);
            String url = "http://192.168.80.192:8888/" + storePath.getFullPath();
            return R.ok().setData(url);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return R.error().setMsg("上传失败");
    }

    @Override
    public R getAddGift(TbGift tbGift) {
        tbGift.setCreateTime(new Date());
        tbGift.setCreateBy("管理员");
        tbGift.setGiftStatus(0);
        tbGiftMapper.insert(tbGift);



        kafkaTemplate.send("topic-gift", tbGift.getGiftId().toString());

        redisTemplate.opsForValue().set("kafka-"+tbGift.getGiftId(),"1");
        return R.ok();
    }

    @KafkaListener(topics = "topic-gift")
    public void recf(String message, Acknowledgment acknowledgment) {
        //发送卡夫卡消息
        String mobile="19537444444";
        MobileMessageUtil.sendMobileMessage(mobile,"尊敬的用户您的礼金券已经领取成功");
        String key="kafka-"+message;
        Boolean aBoolean = redisTemplate.hasKey(key);
        if(!aBoolean){
            //数据已被消费
            R.error().setMsg("数据已被消费");
        }
        //消费完数据删除数据
        acknowledgment.acknowledge();
        //删除key
        redisTemplate.delete(key);

    }

    @Override
    public R getAddStrate() {

        TbGiftStrategy tbGiftStrategy = new TbGiftStrategy();
        tbGiftStrategy.setGiftDesc("恭喜注册成功");
        tbGiftStrategy.setGiftStatus(0);
        tbGiftStrategy.setGiftFrom(1);
        tbGiftStrategy.setGiftType(1);
        tbGiftStrategy.setCreateBy("管理员");
        tbGiftStrategy.setBeginTime(new Date());
        tbGiftStrategy.setEndTime(new Date());
        tbGiftStrategy.setDisPrice(new BigDecimal(5));
        tbGiftStrategy.setMinPrice(new BigDecimal(10));
        tbGiftStrategy.setGiftName("注册成功发放通用品牌礼金(满10元抵扣5元)");
        tbGiftStrategy.setCreateTime(new Date());
        tbGiftStrategyMapper.insert(tbGiftStrategy);
        TbGift tbGift = BeanUtil.toBean(tbGiftStrategy, TbGift.class);
        tbGiftMapper.insert(tbGift);

        IndexOperations indexOps = elasticsearchRestTemplate.indexOps(TbGiftStrategy.class);
        boolean exists = indexOps.exists();
        if (!exists) {
            //创建索引
            indexOps.create();
            Document mapping = indexOps.createMapping();
            indexOps.putMapping(mapping);
        }
        List<TbGiftStrategy> tbGiftStrategies = tbGiftStrategyMapper.selectList(null);
        elasticsearchRestTemplate.save(tbGiftStrategies);


        return R.ok().setMsg("注册成功发放通用品牌礼金(满10元抵扣5元)");
    }

    @Override
    public R getClaimGift(Integer giftId) {
        //1检查礼金存不存在
        TbGift tbGift = tbGiftMapper.selectById(giftId);
        if (tbGift == null) {
            return R.error().setMsg("礼金不存在");
        }
        //修改状态
        tbGift.setGiftStatus(1);
        tbGiftMapper.updateById(tbGift);
        //添加领取记录

        TbGiftRecord tbGiftRecord = new TbGiftRecord();
        tbGiftRecord.setGiftId(tbGift.getGiftId());
        tbGiftRecord.setGiftName(tbGift.getGiftName());
        tbGiftRecord.setCreateBy("管理员");
        tbGiftRecord.setCreateTime(new Date());
        tbGiftRecord.setGetTime(new Date());
        String token = request.getHeader("token");
        if (token == null) {
            return R.error().setMsg("请先登录");
        }
        Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = body.get("userId", Integer.class);

        tbGiftRecord.setUserId(userId);
        tbGiftRecordMapper.insert(tbGiftRecord);

        //同步Es
        //查看是否有索引
        IndexOperations indexOps = elasticsearchRestTemplate.indexOps(TbGiftRecord.class);
        boolean exists = indexOps.exists();
        if (!exists) {
            //创建索引
            indexOps.create();
            Document mapping = indexOps.createMapping();
            indexOps.putMapping(mapping);
        }
        //同步es
        elasticsearchRestTemplate.save(tbGiftRecord);


        return R.ok();
    }

    @Override
    public R getMyGiftList(Integer statusId) {

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        if (statusId != null) {
            boolQueryBuilder.must(QueryBuilders.termQuery("giftStatus", statusId));
        } else {
            boolQueryBuilder.must(QueryBuilders.matchAllQuery());
        }
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        SearchHits<TbGift> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), TbGift.class);
        if (search.getTotalHits() == 0) {
            QueryWrapper<TbGift> wrapper = new QueryWrapper<>();

            if (statusId != null) {
                wrapper.lambda().eq(TbGift::getGiftStatus, statusId);
            }
            List<TbGift> tbGifts = tbGiftMapper.selectList(wrapper);
            return R.ok().setData(tbGifts);
        }
        List<SearchHit<TbGift>> searchHits = search.getSearchHits();
        ArrayList<TbGift> tbGifts = new ArrayList<>();
        for (SearchHit<TbGift> searchHit : searchHits) {
            TbGift content = searchHit.getContent();
            tbGifts.add(content);
        }

        return R.ok().setData(tbGifts);
    }

    @Override
    public R getAllMyGiftList() {
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        boolQueryBuilder.must(QueryBuilders.matchAllQuery());

        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        SearchHits<TbGift> search = elasticsearchRestTemplate.search(nativeSearchQueryBuilder.build(), TbGift.class);
        if (search.getTotalHits() == 0) {
            QueryWrapper<TbGift> wrapper = new QueryWrapper<>();

            List<TbGift> tbGifts = tbGiftMapper.selectList(null);
            return R.ok().setData(tbGifts);
        }
        List<SearchHit<TbGift>> searchHits = search.getSearchHits();
        ArrayList<TbGift> tbGifts = new ArrayList<>();
        for (SearchHit<TbGift> searchHit : searchHits) {
            TbGift content = searchHit.getContent();
            tbGifts.add(content);
        }

        return R.ok().setData(tbGifts);
    }

    @PostConstruct
    public void getEsGiftList() {
        //查看是否有索引
        IndexOperations indexOps = elasticsearchRestTemplate.indexOps(TbGift.class);
        boolean exists = indexOps.exists();
        if (!exists) {
            //创建索引
            indexOps.create();
            Document mapping = indexOps.createMapping();
            indexOps.putMapping(mapping);
        }
        List<TbGift> tbGifts = tbGiftMapper.selectList(null);
        elasticsearchRestTemplate.save(tbGifts);
    }
}




